﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using ServiceStack.Redis;

namespace Redis.Core
{
    /// <summary>
    /// Redis List对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RedisList<T> : RedisBase
    {
        public RedisList(Manager manager, String ListName)
            : base(manager.GetClient())
        {
            Name = ListName;
        }

        public RedisList(String ListName)
            : base(Manager.Default.GetClient())
        {
            Name = ListName;
        }


        


        public void PrependRange(IEnumerable<T> collection)
        {
            List<String> datas = new List<String>();
            foreach (var item in collection)
            {
                datas.Add(JsonConvert.SerializeObject(item, Formatting.None, timeConverter));
            }
            Redis.PrependRangeToList(Name, datas);
        }
        


        public void AddRange(IEnumerable<T> collection)
        {
            List<String> datas = new List<String>();
            foreach (var item in collection)
            {
                datas.Add(JsonConvert.SerializeObject(item, Formatting.None, timeConverter));
            }
            Redis.AddRangeToList(Name, datas);
        }

        public T Items(Int32 Index)
        {
            String Value = Redis.GetItemFromList(Name, Index);
            return JsonConvert.DeserializeObject<T>(Value);
        }


        public void Set(Int32 Index,T Item)
        {
            String Value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            Redis.SetItemInList(Name, Index, Value);
        }




 

        public IList<T> GetRange(Int32 start,Int32 end)
        {
            List<T> Result = new List<T>();
            List<String> Values = Redis.GetRangeFromList(Name, start, end);
            if (Values == null || Values.Count == 0)
                return Result;
            foreach (var item in Values)
            {
                Result.Add(JsonConvert.DeserializeObject<T>(item));
            }
            return Result;
        }

        public IList<T> Sort(SortOptions sortOptions)
        {
            List<T> Result = new List<T>();
            List<String> Values = Redis.GetSortedItemsFromList(Name, sortOptions);
            if (Values == null || Values.Count == 0)
                return Result;
            foreach (var item in Values)
            {
                Result.Add(JsonConvert.DeserializeObject<T>(item));
            }
            return Result;
        }



        public IList<T> Items()
        {
            List<T> Result = new List<T>();
            List<String> Values = Redis.GetAllItemsFromList(Name);
            if (Values == null || Values.Count == 0)
                return Result;
            foreach (var item in Values)
            {
                Result.Add(JsonConvert.DeserializeObject<T>(item));
            }
            return Result;
        }


        //PrependItemToList


        public void Prepend(T Item)
        {
            String Value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            Redis.PrependItemToList(Name, Value);
        }

        public void Add(T Item)
        {
            String Value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            Redis.AddItemToList(Name, Value);
        }

        public Int64 Remove(T Item)
        {
            String Value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            return Redis.RemoveItemFromList(Name, Value);
        }



        public void Push(T Item)
        {
            String Value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            Redis.PushItemToList(Name, Value);
        }

        public T Pop()
        {
            String Value = Redis.PopItemFromList(Name);
            return JsonConvert.DeserializeObject<T>(Value);
        }

        public void Enqueue(T Item)
        {
            String Value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            Redis.EnqueueItemOnList(Name, Value);
        }


        public T Dequeue()
        {
            String Value = Redis.DequeueItemFromList(Name);
            return JsonConvert.DeserializeObject<T>(Value);
        }


        public Boolean ExpireAt(DateTime expireAt)
        {
            return Redis.ExpireEntryAt(Name, expireAt);
        }


        public Boolean ExpireAt(TimeSpan expireIn)
        {
            return Redis.ExpireEntryIn(Name, expireIn);
        }

        public Boolean ExpireAt(Int32 expireIn)
        {
            return Redis.ExpireEntryIn(Name, new TimeSpan(0, 0, 0, 0, expireIn));
        }


        public void Rename(String newName)
        {
            Redis.RenameKey(Name,newName);
            Name = newName;
        }



        public void Clear()
        {
            Redis.RemoveAllFromList(Name);
        }



        public Int64 Count
        {
            get
            {
                return Redis.GetListCount(Name);
            }
        }


        public TimeSpan GetTimeToLive()
        {
            return Redis.GetTimeToLive(Name);
        }

        public Boolean IsExist
        {
            get
            {
                return Redis.ContainsKey(Name);
            }
        }



        public void Delete()
        {
            Redis.Remove(Name);
        }



        public String Name { get; set; }


        private static Newtonsoft.Json.Converters.IsoDateTimeConverter timeConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter()
        {
            DateTimeFormat = "yyyy-MM-dd HH:mm:ss ffff"
        };

    }
}
